package api;

import dto.studentInfo;
import mapper.mysqlMapper;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author hxc
 * @dateTime: 2021/11/18
 * @description: 用于通过分割完整的excel的sheet，把一个个sheet生成一个个独立的excel
 *
 * */
public class spliteExcel {
    //编写一个方法，以便在启动进行调用
    public static void spliteExcel(mysqlMapper mapper)throws IOException {
        //调用获取的所有学生学号
        List<String> schoolNumber=getSchoolNumber.getNumber(mapper);

        //调用获取的所有成绩数据
        List<studentInfo> ScoreData=getData.getScore(mapper);

        //获取所有学生信息
        List<studentInfo> personal=mapper.findStudentInfo();

        //定义一个本地路径，用于存放创建的excel
        String excelPath="D:\\fileUpload\\"+"全部学生成绩excel.xlsx";

        //new 一个Workbook（创建excel）
        Workbook workbook=new XSSFWorkbook();

        //定义标题行
        String[] title={"序号","学号","姓名","年龄","性别","类型","成绩"};

        //样式设置
        CellStyle style=workbook.createCellStyle();

        //excel row和cell代表横纵
        //初始化Cell
        Cell cell=null;

        //初始化sheet名称
        String sheetName=null;

        //遍历生成多个sheet，sheet名以学生学号命名
        //集合长度用size获取，数组用length获取
        for(int i=0;i<schoolNumber.size();i++){
            sheetName=schoolNumber.get(i);
            //创建sheet个数，根据获取到的学生学号个数进行创建，即几个学生创建几个sheet
            workbook.createSheet();
            //给每个sheet设置sheet名称
            workbook.setSheetName(i,sheetName);
            //给每个sheet创建首行，即标题行
            workbook.getSheetAt(i).createRow(0);
        }

        //把写好的标题写入每个sheet文件
        //遍历sheet个数
        for(int i=0;i<schoolNumber.size();i++){
            //遍历标题个数
            for(int j=0;j<title.length;j++){
                //根据标题的个数，创建不同的Cell
                //获取第i个sheet的标题行，并创建第j个cell格子
                cell=workbook.getSheetAt(i).getRow(0).createCell(j);
                //给格子设置值和样式
                cell.setCellValue(title[j]);
                cell.setCellStyle(style);
                //单元格自适应
                workbook.getSheetAt(i).autoSizeColumn(i,true);
            }
        }

        /**
         * 往不同的sheet插入数据
         * 根据sheet名，在每个sheet插入对应的学生的成绩
         * */

        //定义sheet总数进行循环
        int SheetNum=workbook.getNumberOfSheets();
        //初始化row
        Row row=null;
        //遍历sheet总数
        for(int i=0;i<SheetNum;i++){
            //判断sheet名称和学生学号是否相同
            if(workbook.getSheetName(i).equals(schoolNumber.get(i))){
                //定义一个集合，装这个学生的数据
                //这一步主要目的是把一个学生的所有数据的弄到一个集合进行添加到sheet里
                List<studentInfo> studentInfos=new ArrayList<studentInfo>();

                //遍历所有学生的成绩数据
                for(studentInfo data:ScoreData){
                    //遍历学生学号数据
                    for (int j=0;j<schoolNumber.size();j++){
                        //判断所有学生成绩数据里的学生学号是否和获取到的学生学号集合相等
                        if(data.getSchoolNumber().equals(schoolNumber.get(i))){
                            //相等则把数据添加到新创的集合
                            studentInfos.add(data);
                            //当查询到sheet名称和学生学号相等时继续
                            //否则跳出循环，不然会所有人的数据都加入集合，相当于遍历白做
                            if(schoolNumber.get(i).equals(schoolNumber.get(j))){
                                continue;
                            }else{
                                break;
                            }
                        }
                    }


                }
                //获取到这个学生的所有成绩后，把数据插入到对应的数据
                //遍历该学生的集合
                for(int g=0;g<studentInfos.size();g++){
                    //创建行
                    row=workbook.getSheetAt(i).createRow(g+1);
                    //设置序号自增
                    row.createCell(0).setCellValue(g+1);
                    //这个集合有数据的是学号、类型和分数
                    //插入学号
                    row.createCell(1).setCellValue(studentInfos.get(g).getSchoolNumber());
                    //插入类型
                    row.createCell(5).setCellValue(studentInfos.get(g).getType());
                    //插入分数
                    row.createCell(6).setCellValue(studentInfos.get(g).getScore());
                    //根据学号，去插入获取到的学生个人信息
                    //遍历学生个人信息集合
                    for(int m=0;m<personal.size();m++){
                        //判断个人信息里的学号和插入的学生学号是否相等，相等就插入姓名和年龄等
                        if(row.getCell(1).getStringCellValue().equals(personal.get(m).getSchoolNumber())){
                            //插入姓名
                            row.createCell(2).setCellValue(personal.get(m).getName());
                            //插入年龄
                            row.createCell(3).setCellValue(personal.get(m).getAge());
                            //插入性别
                            row.createCell(4).setCellValue(personal.get(m).getSex());
                        }
                        //根据标题的文字设置单元格大小
                        for(int h=0;h<title.length;h++){
                            workbook.getSheetAt(i).setColumnWidth(h,workbook.getSheetAt(i).getRow(0).getCell(0).getStringCellValue().getBytes().length*1000+100);
                        }
                    }
                }
                //最后要清空集合的数据，防止前一个人的成绩加入到下一个sheet
                System.out.println(studentInfos);
                studentInfos.clear();
            }
        }

        //创建本地excel文件
        //创建文件，路径为excelPath
        File file =new File(excelPath);
        //文件如果不存在，则创建父级文件夹，不然会整个文件都创建为文件夹
        if(!file.exists()){
            file.getParentFile().mkdirs();
        }
        //创建xlsx文件,这里要抛出异常
        file.createNewFile();
        //以流的形式输出文件
        FileOutputStream fileOutputStream=new FileOutputStream(file);
        //设置创建excel的路径和文件名
        workbook.write(fileOutputStream);
        fileOutputStream.close();

        /**
         * 这里开始正式的拆分excel
         * 把sheet拆分为一个个的独立excel
         *
         * */
        //查找完整的excel文件
        XSSFWorkbook xssfWorkbook=new XSSFWorkbook(new FileInputStream(new File(excelPath)));
        //定义遍历完整的excel的sheet数
        int total=xssfWorkbook.getNumberOfSheets();
        //遍历sheet
        for(int i=0;i<total;i++){
            //查找创建的完整excel并加入创建文件
            File sheetFile=new File(excelPath);
            //先创建相同的excel文件
            XSSFWorkbook sheetWorkbook=new XSSFWorkbook(new FileInputStream(sheetFile));
            //定义一个total2，为新创建的excel的sheet总数
            int total2=sheetWorkbook.getNumberOfSheets();
            //遍历
            for(int j=total2-1;j>=0;j--){
                //当原本的多sheet文件和现在新创建的sheet位置是相等的时候，继续执行
                if(i==j){
                    continue;
                }
                //否则删除其他sheet
                sheetWorkbook.removeSheetAt(j);

            }
            //以下写在遍历生成excel的循环里
            //定义拆分后的shhet路径和名称
            String spliteExcelPath="D:\\fileUpload\\"+xssfWorkbook.getSheetName(i)+".xlsx";
            //写了以下的判断文件代码，可以放在任意一个位置的路径
            File spliteFile=new File(spliteExcelPath);
            if(!spliteFile.exists()){
                spliteFile.getParentFile().mkdirs();
            }
            spliteFile.createNewFile();
            FileOutputStream sheetCreate=new FileOutputStream(spliteFile);
            sheetWorkbook.write(sheetCreate);
            sheetCreate.close();
        }

        System.out.println("拆分excel成功！");
    }

}
